package com.example.apidocserver.infrastructure.util.document;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.example.apidocserver.domain.document.dto.MenuApiNodeDto;
import com.example.apidocserver.domain.document.dto.UploadMenuApiDto;
import com.example.apidocserver.domain.document.entity.ApiInfo;
import com.example.apidocserver.domain.document.entity.ApiParamHis;
import com.example.apidocserver.domain.document.entity.DocMenu;
import com.example.apidocserver.infrastructure.util.StringIdUtil;
import org.springframework.util.CollectionUtils;

import java.util.Objects;

import static com.example.apidocserver.infrastructure.constants.SystemConstants.*;
import static com.example.apidocserver.infrastructure.constants.TalendJsonConstants.*;

/**
 * json对象转文档实体类工具
 *
 * @author xyqlg
 */
public class TalendJsonToEntity {
    /**
     * 设置参数示例
     *
     * @param menuApiDto 导入解析所有数据对象
     * @param entity     需要解析的入参对象
     * @param node       当前节点信息
     */
    public static void setApiParamHis(UploadMenuApiDto menuApiDto, JSONObject entity, MenuApiNodeDto node) {
        String bodyStr = getBodyStr(entity);

        String queryStr = getQueryStr(entity);

        String hdStr = getHdStr(entity);

        if (!StringUtils.isEmpty(bodyStr) || !StringUtils.isEmpty(queryStr) || !StringUtils.isEmpty(hdStr)) {
            DocMenu menu = node.getNode();
            ApiParamHis apiParamHis = new ApiParamHis();
            apiParamHis.setEnvId(YES).setEnableFlag(YES).setParamInputBodyStr(bodyStr)
                    .setParamInputQueryStr(queryStr).setParamInputHeaderStr(hdStr).setParamDesc(menu.getMenuName())
                    .setParamName(menu.getMenuName()).setOrderNo(YES).setParamInputPathStr("")
                    .setParamOutputHeaderStr("").setParamOutputBodyStr("").setCreateTime(menuApiDto.getNow())
                    .setUpdateTime(menuApiDto.getNow()).setCreator(menuApiDto.getUserId())
                    .setUpdater(menuApiDto.getUserId());
            node.setApiParamHis(apiParamHis);
            menuApiDto.getApiParamHisList().add(apiParamHis);
        }
    }

    private static String getHdStr(JSONObject entity) {
        String hdStr = "";
        JSONArray headers = entity.getJSONArray(FS_HEADERS);
        if (!CollectionUtils.isEmpty(headers)) {
            StringBuilder sb = new StringBuilder();
            for (int h = 0; h < headers.size(); h++) {
                JSONObject headerOne = headers.getJSONObject(h);
                sb.append(headerOne.getString(FS_NAME)).append(":").append(headerOne.getString(FS_VALUE)).append("\n");
            }
            hdStr = sb.toString();
        }
        return hdStr;
    }

    private static String getQueryStr(JSONObject entity) {
        String queryStr = "";
        JSONObject uri = entity.getJSONObject(FS_URI);
        if (Objects.isNull(uri)) {
            return queryStr;
        }
        JSONObject query = uri.getJSONObject(FS_QUERY);
        if (Objects.isNull(query)) {
            return queryStr;
        }
        JSONArray items = query.getJSONArray(FS_ITEMS);
        if (!CollectionUtils.isEmpty(items)) {
            StringBuilder sb = new StringBuilder("?");
            for (int j = 0; j < items.size(); j++) {
                JSONObject queryOne = items.getJSONObject(j);
                sb.append(queryOne.getString(FS_NAME)).append("=").append(queryOne.getString(FS_VALUE)).append(QUERY_AND_STR);
            }
            sb.deleteCharAt(sb.length() - 1);
            queryStr = sb.toString();
        }
        return queryStr;
    }

    private static String getBodyStr(JSONObject entity) {
        JSONObject body = entity.getJSONObject(FS_BODY);
        String bodyType = body.getString(FS_BODY_TYPE);
        String bodyStr = "";
        if (VS_TEXT.equals(bodyType)) {
            bodyStr = body.getString(FS_TEXT_BODY);
        }
        return bodyStr;
    }

    /**
     * 设置接口信息
     *
     * @param menuApiDto 导入解析所有数据对象
     * @param entity     需要解析的入参对象
     * @param node       当前节点信息
     * @param spaceId    工作空间id
     */
    public static void setApiInfo(UploadMenuApiDto menuApiDto, JSONObject entity, MenuApiNodeDto node, Integer spaceId) {
        DocMenu menu = node.getNode();
        menu.setMenuType(MENU_URI_TYPE).setApiName(menu.getMenuName()).setApiDesc(menu.getDesc());

        JSONObject method = entity.getJSONObject(FS_METHOD);
        String methodName = method.getString(FS_NAME);
        JSONObject uri = entity.getJSONObject(FS_URI);
        String path = uri.getString(FS_PATH);
        if (StringUtils.isEmpty(path)) {
            path = DF_URI + StringIdUtil.generateUUID();
        }

        ApiInfo apiInfo = new ApiInfo();
        node.setApiInfo(apiInfo);
        menuApiDto.getApiInfoList().add(apiInfo);
        // TODO owner判断权限
        apiInfo.setApiType(methodName).setApiUri(path).setApiHeader(HTTP_DEF_HEADER).setApiName(menu.getApiName())
                .setApiDesc(menu.getApiDesc()).setSpaceId(spaceId)
                .setOwner(menuApiDto.getUserId()).setEnableFlag(YES).setStateId(DM_ONLY_FIELD).setServerId(DATA_COMMON_ID)
                .setCreateTime(menuApiDto.getNow()).setUpdateTime(menuApiDto.getNow())
                .setCreator(menuApiDto.getUserId()).setUpdater(menuApiDto.getUserId());
    }

    /**
     * 创建Node对象、设置当前节点node的目录信息
     *
     * @param menuApiDto 导入解析所有数据对象
     * @param nodeParent 上级节点
     * @param docId      文档id
     * @param order      排序
     * @param entity     需要解析的入参对象
     * @return 当前节点信息
     */
    public static MenuApiNodeDto getNodeSetMenu(UploadMenuApiDto menuApiDto, MenuApiNodeDto nodeParent, Integer docId,
                                                int order, JSONObject entity) {
        String menuName = entity.getString(FS_NAME);
        DocMenu docMenu = new DocMenu();
        docMenu.setMenuName(menuName).setMenuType(MENU_MENU_TYPE)
                .setDocId(docId).setEnableFlag(YES).setOrderNo(order).setPrimaryFlag(NO).setDesc(menuName)
                .setCreateTime(menuApiDto.getNow()).setCreator(menuApiDto.getUserId())
                .setUpdateTime(menuApiDto.getNow()).setUpdater(menuApiDto.getUserId());
        MenuApiNodeDto node = MenuApiNodeDto.builder().node(docMenu).parentNode(nodeParent.getNode())
                .lvl(nodeParent.getLvl() + 1).build();
        menuApiDto.getMenuNodeList().add(node);
        menuApiDto.getMenuList().add(docMenu);
        return node;
    }
}
